package com.exam.api.common.utils;


import lombok.SneakyThrows;

import java.util.concurrent.TimeUnit;

/**
 * @Author 北橙
 * @Create 2023/3/7
 * @Description 同步重试工具类
 * @Version 1.0
 */
public class RetryUtil {
    /**
     * 重试操作，最多重试maxRetries次，每次重试等待waitTimeMillis毫秒
     *
     * @param maxRetries     最多重试次数
     * @param waitTimeMillis 重试等待时间，单位为毫秒
     * @param retryTask      需要重试的任务
     * @return 重试成功返回任务的返回值，重试次数用完仍然失败则抛出异常
     * @throws Exception 重试次数用完仍然失败则抛出异常
     */
    @SneakyThrows
    public static <T> T retryOnException(int maxRetries, long waitTimeMillis, RetryTask<T> retryTask)   {
        int retries = 0;
        while (retries < maxRetries) {
            try {
                return retryTask.execute();
            } catch (Exception e) {
                retries++;
                if (retries >= maxRetries) {
                    throw e;
                }
                TimeUnit.MILLISECONDS.sleep(waitTimeMillis);
            }
        }
        throw new Exception("Retry failed after " + maxRetries + " attempts.");
    }

    /**
     * 可重试的任务接口
     */
    public interface RetryTask<T> {
        T execute() throws Exception;
    }
}
